﻿// Open Source: MIT License (http://www.opensource.org/licenses/mit-license.php)
// Project: YoProgramo.NET (http://code.google.com/p/yoprogramo/)
// Autor: Fabian Figueredo (info@fabianfigueredo.com.ar)
// Blog: blog.yoprogramo.net

using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;
using log4net;
using log4net.Config;
using Microsoft.Practices.ServiceLocation;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
using NHibernate.Validator.Cfg;
using NHibernate.Validator.Engine;
using YoProgramo.Domain.BusinessLogic.Extensions;
using YoProgramo.Domain.BusinessLogic.Service;
using YoProgramo.Domain.Core.Exceptions;
using YoProgramo.Domain.Core.Interfaces;
using YoProgramo.Infrastructure.Data.NHIbernate;
using YoProgramo.Infrastructure.Data.Repositories;
using YoProgramo.Infrastructure.Tools.Configuration;
using YoProgramo.Infrastructure.Tools.Windsor;
using YoProgramo.Infrastructure.UI.Routes;
using Environment=System.Environment;


namespace YoProgramo.Infrastructure.UI.Web
{
    public class YpMvcApplication : System.Web.HttpApplication {

        private static readonly ILog log = LogManager.GetLogger(typeof(YpMvcApplication));

        public static void RegisterRoutes(RouteCollection routes) {
            RouteHelper.SetRoutes(routes);
        }

        protected void Application_Start() {
            // Initialize log4net
            XmlConfigurator.Configure();

            // Initialize SiteConfiguration
            YoProgramoConfigurationManager.Configure();

            //Set IoC
            IoChelper ioc = new IoChelper();
            windsorContainer = ioc.Initialize();

            ioc.RegisterControllers(Assembly.LoadFrom(Server.MapPath("~/bin/YoProgramo.Web.dll")));
            ioc.AddCoreTypesTo(typeof(IStory).Assembly);
            ioc.AddServiciesTo(typeof(IUserService).Assembly);
            ioc.AddRepositoriesTo(typeof(RepositoryBase<,,>).Assembly);            
            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(windsorContainer));

            //Set ServiceLocator
            ServiceLocator.SetLocatorProvider(
                () => new WindsorServiceLocator(windsorContainer));

            //Set NHIbernate
            new NHWrapper(Server.MapPath("~/hibernate.config"));
            NHWrapper.CreateSession();            

            //Set NHIbernate Validator            
            ValidatorEngine engine = new ValidatorEngine();
            engine.Configure(); 
            ValidatorInitializer.Initialize(NHWrapper._config, engine);

            /*SchemaExport shemaexport = new SchemaExport(NHWrapper._config);
            shemaexport.SetOutputFile(Server.MapPath("./") + "basededatos.sql");
            shemaexport.Create(true, true);*/

            //Set Routes
            RegisterRoutes(RouteTable.Routes);
            //RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);

            log.Info("Web Application Start.- Time: " + DateTime.Now);
        }


        protected void Application_Error(Object sender, EventArgs e)
        {
            /*
            Exception ex = Server.GetLastError();

            if (ex is YPIsLockedException)
            {
                Response.Redirect("/Error/IsLocked/");
            }
            else
            {
                //Default Error
                Response.Redirect("/Error/Unknown/");
                log.Fatal("Fatal error", ex);                
            }            
            Server.ClearError();
             * */
        }

        protected void Application_BeginRequest(Object sender, EventArgs e) {
            if(YoProgramoConfigurationManager.GetCurrentConfiguration().EnableHostsWhenClose.Contains(Request.UserHostAddress))
                return;

            if (YoProgramoConfigurationManager.IsSiteLocked())
            {
                if (!Request.Url.AbsoluteUri.ToLower().Contains("/error/")
                    && !Request.Url.AbsoluteUri.ToLower().Contains("/error.mvc/")
                    && !Request.Url.AbsoluteUri.ToLower().Contains("/unknown")
                    && !Request.Url.AbsoluteUri.ToLower().Contains("/islocked")
                    && !Request.Url.AbsoluteUri.ToLower().Contains("/views/shared/")
                    && !Request.Url.AbsoluteUri.ToLower().Contains("/content/site.css")
                    && !Request.Url.AbsoluteUri.ToLower().Contains("/content/images/")                    
                    ) {
                        Response.Redirect("/Error/IsLocked/");
                    }
            }
        }

        protected void Session_Start(Object sender, EventArgs e) {
            if(HttpContext.Current.User.Identity.IsAuthenticated)            
            {
                IUser user = ServiceLocator.Current.GetInstance<IUserRepository>().FindByUserName(HttpContext.Current.User.Identity.Name);
                user.ToEnableCheck();
            }
        }

        /// <summary>
        /// Implements <see cref="IContainerAccessor" /> so that Castle facilities
        /// can gain access to the <see cref="HttpApplication" />.
        /// </summary>
        public IWindsorContainer Container {
            get { return windsorContainer; }
        }

        /// <summary>
        /// Provides a globally available access to the <see cref="IWindsorContainer" /> instance.
        /// </summary>
        public static IWindsorContainer WindsorContainer {
            get { return windsorContainer; }
        }

        private static IWindsorContainer windsorContainer;

    }
}